package br.ufpe.cin.xmldbdev.dados.xml;

import java.io.File;

import javax.xml.transform.stream.StreamSource;

import net.sf.saxon.Configuration;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.SequenceIterator;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.query.StaticQueryContext;
import net.sf.saxon.query.XQueryExpression;
import net.sf.saxon.trans.XPathException;



/**
 * This is an auxiliary class to read XML files nodes.
 * 
 * @author M2S
 * 
 */
public class XMLFileReader {

	/** The file that this class will use to read the file. */
	private File file;

	/**
	 * Constructor.
	 * 
	 * @param theFile
	 *            to be read
	 */
	public XMLFileReader(File theFile) {
		this.file = theFile;
	}

	/**
	 * Constructor.
	 * 
	 * @param filePath
	 *            to the file to be read
	 */
	public XMLFileReader(String filePath) {
		this.file = new File(filePath);
	}

	/**
	 * Reads the content of a node inside the xml file. If there is more than
	 * one node with the given name, the content of the first found node will be
	 * returned. There's no guarantee that the first found node will be the
	 * first node in the document or in any other order.
	 * 
	 * @param nodeName
	 *            the node which content will be returned
	 * @return a String that represents the content of the node
	 * @throws XPathException
	 *             is raised if an error occurs. i.e. file not found
	 * @throws net.sf.saxon.trans.XPathException 
	 */
	public String readNode(String nodeName) throws XPathException {
		String result = "";
		Configuration cfg = new Configuration();
		StaticQueryContext staticContext = new StaticQueryContext(cfg);
		DynamicQueryContext dynamicContext = new DynamicQueryContext(cfg);
		XQueryExpression exp = staticContext.compileQuery("//" + nodeName);
		dynamicContext.setContextItem(cfg.buildDocument(new StreamSource(
				this.file)));
		SequenceIterator nodes = exp.iterator(dynamicContext);
		NodeInfo nodeInfo = (NodeInfo) nodes.next();
		if (nodeInfo != null) {
			result = nodeInfo.getStringValue();
		}
		return result;
	}
	/**
	 * get the number of the nodes with the name parameter.
	 * @param nodeName
	 * 	the name of the node.
	 * @return
	 * 	the quantity of node with this name.
	 * @throws XPathException
	 * 	if occurs a XML error.
	 */
	public int numberOfNodes(String nodeName) throws XPathException {
		if (!file.exists()) {
			return 0;
		}
		Configuration cfg = new Configuration();
		StaticQueryContext staticContext = new StaticQueryContext(cfg);
		DynamicQueryContext dynamicContext = new DynamicQueryContext(cfg);
		XQueryExpression exp = staticContext.compileQuery("//" + nodeName);
		dynamicContext.setContextItem(cfg.buildDocument(new StreamSource(
				this.file)));
		SequenceIterator nodes = exp.iterator(dynamicContext);
		
		int count = 0;
		NodeInfo node = (NodeInfo) nodes.next();
		while (node != null) {
			count++;
			node = (NodeInfo) nodes.next();
		}		
		return count;
	}
	/**
	 * Read the content of the node.
	 * @param nodeName
	 * 	the node name.
	 * @param index
	 * 	the node index.
	 * @return
	 * 	the node content.
	 * @throws XPathException
	 *  if occurs a XML error.
	 */
	public String readNode(String nodeName, int index) throws XPathException {
		Configuration cfg = new Configuration();
		StaticQueryContext staticContext = new StaticQueryContext(cfg);
		DynamicQueryContext dynamicContext = new DynamicQueryContext(cfg);
		XQueryExpression exp = staticContext.compileQuery("//" + nodeName);
		dynamicContext.setContextItem(cfg.buildDocument(new StreamSource(
				this.file)));
		SequenceIterator nodes = exp.iterator(dynamicContext);
		
		int count = 0;
		String str = null;
		NodeInfo node = (NodeInfo) nodes.next();
		while (node != null) {
			if (count == index) {
				return node.getStringValue();				
			}
			count++;
			node = (NodeInfo) nodes.next();
		}		
		return str;		
	}
	
	public void deleteFile(){
		file.delete();
	}
	
}
